﻿using Dyao.Book.Application.Abstractions;
using Dyao.Book.Contract;
using Dyao.Book.Core;
using Dyao.Book.Repository.Abstractions;
using Foundation.Core;
using Foundation.Uow;
using Microsoft.Extensions.Logging;

namespace Dyao.Book.Application
{
    public class QiDianBookContentPlugins : BaseBookContentPlugins, IBusinessPlugin<BookContentPluginsContext>
    {
        /// <summary>
        /// 书源
        /// </summary>
        public override string SourceKey { get; set; } = BookSourceType.QiDian.ToString();

        private readonly ILogger<QiDianBookContentPlugins> _logger;

        private readonly IUnitOfWorkManager _unitOfWorkManager;

        private readonly IQiDianBookCatalogueContentSpider _crawlBookContentSpider;

        public QiDianBookContentPlugins(IBookCatalogueRepository catalogueRepository,
            ILogger<QiDianBookContentPlugins> logger,
            IUnitOfWorkManager unitOfWorkManager,
            IQiDianBookCatalogueContentSpider crawlBookContentSpider) : base(catalogueRepository)
        {
            _logger = logger;
            _unitOfWorkManager = unitOfWorkManager;
            _crawlBookContentSpider = crawlBookContentSpider;
        }


        public async Task ExecuteAsync(BookContentPluginsContext executeContext, Func<BookContentPluginsContext, CancellationToken, Task> next, CancellationToken cancellationToken)
        {
            await _logger.LogConsumeTimeAsync(async () =>
            {
                if (executeContext == null) throw new ArgumentNullException(nameof(executeContext));

                using (var unitOfWork2 = _unitOfWorkManager.Begin(requiresNew: true))
                {
                    var chapters = (List<CrawCatalogueContentDto>)executeContext.Collection;
                    var filterChapters = chapters.Where(c => c.SourceKey == SourceKey);
                    if (filterChapters.Any())
                        await _crawlBookContentSpider.CrawlContentByCataloguesAsync(filterChapters.ToList(), cancellationToken);

                    // 区分手动
                    var hasNext = new List<BookNotCrawlChapterDto>();
                    if (executeContext.Args.IsManual)
                    {
                        hasNext = ((List<CrawCatalogueContentDto>)executeContext.Collection)
                        .Where(c => c.SourceKey != SourceKey)
                        .Select(h => new BookNotCrawlChapterDto() { Id = h.BookCatalogueId, SourceKey = h.SourceKey, ContentLink = h.ContentLink })
                        .ToList();
                    }
                    else
                        hasNext = await GetNotCrawlCompalteChaptersAsync(executeContext.Args.BookId, cancellationToken);

                    // 有下一页匹配
                    if (hasNext.Any())
                    {
                        executeContext.Collection = hasNext.Select(h => new CrawCatalogueContentDto() { BookCatalogueId = h.Id, ContentLink = h.ContentLink, SourceKey = h.SourceKey }).ToList();
                        await next(executeContext, cancellationToken);
                    }
                }

            }, "ExecuteAsync");
        }
    }
}
